home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cjdates.exe / DATES.LST < prev    next >
File List  |  1991-07-21  |  27KB  |  499 lines

  1. Turbo Assembler     Version 2.5        07/21/91 16:39:26        Page 1
  2. dates.ASM
  3.  
  4.  
  5.  
  6.       1                         %PAGESIZE 58,124
  7.       2                     ;*******************************************************************************
  8.       3                     ;
  9.       4                     ;                       ZDAY and    ZDATE
  10.       5                     ;
  11.       6                     ; These are routines for converting Gregorian dates to and    from Day Numbers.
  12.       7                     ;
  13.       8                     ; The routines are    called using the PASCAL    calling    sequence, and are FAR calls.
  14.       9                     ; All pointers are    FAR pointers.
  15.      10                     ;
  16.      11                     ; The routines are    written    to run on an 8088 so as    to be compatible with all
  17.      12                     ; machines    based on this architecture, and    use the    Borland    "PASCAL" calling
  18.      13                     ; sequence    so as to be callable from programs compiled with both Borland's    C
  19.      14                     ; and Pascal compilers.
  20.      15                     ;
  21.      16                     ; The Borland Turbo Assembler (V2.0 or better) is required    to assemble this code.
  22.      17                     ;
  23.      18                     ;===============================================================================
  24.      19                     ;
  25.      20                     ; The C calling sequences are defined by these prototypes:
  26.      21                     ;
  27.      22                     ; unsigned    long int far pascal ZDay( unsigned int Year, unsigned int Month,
  28.      23                     ;                                  unsigned int Day );
  29.      24                     ;
  30.      25                     ; int far pascal ZDate(unsigned long int DayNumber, unsigned int far *Year,
  31.      26                     ;                    unsigned int far *Month, unsigned int far *Day );
  32.      27                     ;
  33.      28                     ;-------------------------------------------------------------------------------
  34.      29                     ;
  35.      30                     ; The PASCAL prototypes (you will $L the object code from this assembly into
  36.      31                     ; a TPU) would be:
  37.      32                     ;
  38.      33                     ; function    ZDay(Year, Month, Day :    word) :    longint;
  39.      34                     ;
  40.      35                     ; function    ZDate(DayNumber    : longint; var Year, Month, Day    : word ) : boolean;
  41.      36                     ;
  42.      37                     ;-------------------------------------------------------------------------------
  43.      38                     ;
  44.      39                     ; ZDay returns a 32-bit unsigned integer representing the Day Number calculated
  45.      40                     ; from the    supplied Gregorian date.  Although the Pascal call defines it as a
  46.      41                     ; longint,    you will not have to worry about getting a negative number back.
  47.      42                     ;
  48.      43                     ; If the resulting    Day Number is zero, you    have supplied a    Gregorian date that
  49.      44                     ; is too early or too far in the future for the calculations to be    performed
  50.      45                     ; correctly with this routine's methods.
  51.      46                     ;
  52.      47                     ; The Year, Month and Day parameters are all unsigned 16-bit integers,  Year
  53.      48                     ; must be the FULL    YEAR.  1902 must be supplied as    1902, not 02.  It must be
  54.      49                     ; in the range 1 to 25599 or zero will be returned.  Month    and Day    must be    in
  55.      50                     ; the range 0-65535.  These restrictions should not be too    restrictive for    most
  56.      51                     ; purposes.
  57.      52                     ;
  58.      53                     ; Note that Day, Month and    Year are all UNSIGNED.    When you are doing weird
  59. Turbo Assembler     Version 2.5        07/21/91 16:39:26        Page 2
  60. dates.ASM
  61.  
  62.  
  63.  
  64.      54                     ; date calculations you must NEVER    try to supply negative values for these.
  65.      55                     ; This is also true of the    any Day    Number you give    to ZDate!  Negative numbers
  66.      56                     ; look like large positive    numbers    and will give Wrong Results!
  67.      57                     ;
  68.      58                     ; The same    parameters are used with ZDate,    except no value    is returned since it
  69.      59                     ; is a procedure (void function) rather than a function.  Just supply the Day
  70.      60                     ; Number, and ZDate fills in the Year, Month and Day for you.  The    supplied Day
  71.      61                     ; Number should be    greater    than 121 and less than 23920640.  For Day Numbers
  72.      62                     ; outside this range, ZDate returns a Gregorian date of 0-0-0 and a return
  73.      63                     ; value of    0 (FALSE in both Pascal    and C).     A good    conversion returns 1 (TRUE
  74.      64                     ; in both C and Pascal).
  75.      65                     ;
  76.      66                     ; NOTE:  ZDay can convert certain dates into Day Numbers that are outside the
  77.      67                     ; range that ZDate    can convert back.  These dates,    however, involve years
  78.      68                     ; that are    either zero or very, very large, and are well outside the range    of
  79.      69                     ; dates that we are likely    to be interested in.
  80.      70                     ;
  81.      71                     ; A call to ZDay uses 14 bytes of space on    the stack; a call to ZDate uses    26.
  82.      72                     ;
  83.      73                     ;===============================================================================
  84.      74                     ;
  85.      75                     ;                 WHAT'S    IT ALL FOR, ANYWAY?
  86.      76                     ;
  87.      77                     ; All dates, valid    or not,    convert    to Day Numbers of some kind.  All Day
  88.      78                     ; Numbers convert to valid    Gregorian dates.  So if    you convert a Gregorian
  89.      79                     ; date to a Day Number and    back, if the resulting Gregorian date doesn't match
  90.      80                     ; the original, the original was invalid.
  91.      81                     ;
  92.      82                     ; The Day Number is related to the    Julian Day Number, but is not the same.
  93.      83                     ; It is valid only    for the    years since the    Gregorian calendar was introduced.
  94.      84                     ;
  95.      85                     ; You can use the Day Numbers of two dates    to find    the number of days between
  96.      86                     ; them.
  97.      87                     ;
  98.      88                     ; The remainder resulting when the    Day Number is divided by 7 is the day of the
  99.      89                     ; week, with 0 (Sunday) thru 6 (Saturday).
  100.      90                     ;
  101.      91                     ; To find the last    day of a month,    begin with the Gregorian date.    Add 1 to
  102.      92                     ; the month (even to December), set the Day to 0, convert to a Day    Number,    then
  103.      93                     ; back to Gregorian.
  104.      94                     ;
  105.      95                     ; To find the Julian day of the year (different from the Julian Day Number!),
  106.      96                     ; convert the given Gregorian date    to a Day Number.  Then subtract    from this
  107.      97                     ; the Day Number of January 0 (NOT    1!) of the same    year.
  108.      98                     ;
  109.      99                     ; Convert a Julian    Date to    Gregorian by taking the    Day Number of of January
  110.     100                     ; ZERO of the year.  Add the Julian day of    the year to this, then convert
  111.     101                     ; to a Gregorian date.
  112.     102                     ;
  113.     103                     ;*******************************************************************************
  114.     104                     ;                            (c) Copyright 1991 Crazy Jack
  115.     105                     ;                                  All Rights Reserved
  116. Turbo Assembler     Version 2.5        07/21/91 16:39:26        Page 3
  117. dates.ASM
  118.  
  119.  
  120.  
  121.     106                         %NEWPAGE
  122.     107                         IDEAL
  123.     108    0000                     MODEL   LARGE
  124.     109    0000                     CODESEG
  125.     110                     ;
  126.     111                     ; The simplest routine converts the Gregorian date    to a Day Number:
  127.     112                     ;
  128.     113    0000                     PROC    PASCAL ZDAY FAR Year:WORD,    Month:WORD, Day:WORD
  129.     114                         PUBLIC  ZDAY
  130. 1   115    0000  55                 PUSH    BP
  131. 1   116    0001  8B EC                 MOV     BP,SP
  132. 1   117    0003  8B 4E 0A                 MOV     CX, [Year]             ;Get Year.
  133.     118    0006  8B 5E 08                 MOV     BX, [Month]         ;Get Month.
  134.     119    0009  83 FB 0E                 CMP     BX, 14             ;Month greater than 14 will give
  135.     120    000C  77 5A                 JA         FIXMNTH             ;incorrect    results.
  136.     121    000E                 MNTHOK:
  137.     122    000E  80 FB 02                 CMP     BL, 2             ;Is Month January or February?
  138.     123    0011  77 08                 JA         NOADJ             ;Jump if not,
  139.     124
  140.     125    0013  0B C9                 OR         CX, CX             ;else be sure year    isn't zero (we're
  141.     126    0015  74 60                 JZ         DATEBAD             ;in trouble if we decrement zero),
  142.     127    0017  49                 DEC     CX                 ;then shift calculations to joint
  143.     128    0018  83 C3 0C                 ADD     BX, 12             ;between February and March.
  144.     129    001B                 NOADJ:
  145.     130    001B  80 FD 64                 CMP     CH, 100             ;Any year too big